﻿using Fuse8.ContentManagementFramework.Administration.Models;
using Fuse8.ContentManagementFramework.BizFacade.Services;
using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Web.ApplicationRuntime;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Fuse8.ContentManagementFramework.Administration.Controllers
{
    public class CmsMediaController : CmsAdminController
    {
        private CmsMediaService _mediaService = new CmsMediaService();
        private CmsMediaFileService _cmsMediaFileService = new CmsMediaFileService();
        private CmsMediaContentService _mediaContenService = null;

        private CmsMediaContentService MediaContentService
        {
            get { return _mediaContenService ?? (_mediaContenService = new CmsMediaContentService()); }
        }

        private IEnumerable<SelectListItem> OrderByModes
        {
            get
            {
                return new[]
                {
                    new SelectListItem() {Value = "", Text = GetText("Order by", "cms_Media")},
                    new SelectListItem() {Value = "AZ", Text = GetText("A-Z", "cms_Media")},
                    new SelectListItem() {Value = "ZA", Text = GetText("Z-A", "cms_Media")},
                    new SelectListItem() {Value = "Updated", Text = GetText("Most Recently Updated", "cms_Media")}
                };
            }
        }


        private IEnumerable<SelectListItem> FilterTypeModes
        {
            get
            {
                return new[]
                {
                    new SelectListItem() {Value = "all", Text = GetText("All types", "cms_Media")},
                    new SelectListItem() {Value = "video", Text = GetText("Videos", "cms_Media")},
                    new SelectListItem() {Value = "image", Text = GetText("Images", "cms_Media")},
                    new SelectListItem() {Value = "audio", Text = GetText("Audio", "cms_Media")},
                    new SelectListItem() {Value = "application", Text = GetText("Documents", "cms_Media")}
                };
            }
        }

        public ActionResult Index(string orderBy = "", string filterType = "all")
        {
            var data = _mediaService.FindWithMimeType(filterType);

            if (orderBy == "ZA")
            {
                data = data.OrderByDescending(e => e.FolderName);
            }
            else if (orderBy == "Updated")
            {
                data = data.OrderByDescending(e => e.DateLastUpdated.GetValueOrDefault(e.DateCreated));
            }
            else
            {
                data = data.OrderBy(e => e.FolderName);
            }

            ViewBag.OrderBySelectList = new SelectList(OrderByModes, "Value", "Text", orderBy);
            ViewBag.FilterTypeSelectList = new SelectList(FilterTypeModes, "Value", "Text", filterType);

            return View(data);
        }

        public ActionResult Add(int? parentId)
        {
            var model = new CmsMedia();
            if (parentId.HasValue)
            {
                model.ParentMediaId = parentId;
            }

            SetFolders();

            return View(model);
        }

        [HttpPost]
        public ActionResult Add(CmsAdminMediaSaveModel model)
        {
            ActionResult result = null;

            if (model != null)
            {
                if (ModelState.IsValid)
                {
                    var originMedia = model.ConvertToMedia();
                    _mediaService.Add(originMedia);

                    result = Request.IsAjaxRequest()
                                 ? RedirectToAction("SelectMedia", new { id = originMedia.Id })
                                 : (!model.ParentMediaId.HasValue
                                        ? RedirectToAction("Index")
                                        : RedirectToAction("Get", new { id = model.ParentMediaId.Value }));
                }
                else
                {
                    SetFolders();
                }
            }

            return result ?? View(model.ConvertToMedia());
        }

        public ActionResult Get(int? id = null, int? page = null, int? size = null, bool isInAjax = false, string orderBy = "", string searchQuery = "")
        {
            ActionResult result = null;
            IEnumerable<CmsMediaContent> mediaContents = null;
            var model = new CmsMediaModel();

            if (id != null && id > 0)
            {
                var data = _mediaService.FindOne(id.Value);

                if (data != null)
                {
                    mediaContents = data.MediaContents;

                    if (data.SubFolders != null)
                    {
                        if (orderBy == "ZA")
                        {
                            data.SubFolders = data.SubFolders.OrderByDescending(e => e.FolderName);
                        }
                        else if (orderBy == "Updated")
                        {
                            data.SubFolders =
                                data.SubFolders.OrderByDescending(
                                    e => e.DateLastUpdated.GetValueOrDefault(e.DateCreated));
                        }
                        else
                        {
                            data.SubFolders = data.SubFolders.OrderBy(e => e.FolderName);
                        }
                    }

                    ViewBag.CurrentMediaId = data.Id;

                    if (!isInAjax)
                    {
                        CmsMedia parentFolder;
                        if (data.ParentMediaId.HasValue)
                        {
                            parentFolder = _mediaService.FindOne(data.ParentMediaId.Value);
                        }
                        else
                        {
                            parentFolder = new CmsMedia();
                        }
                        parentFolder.TotalMediaContent = -1;
                        data.SubFolders = new[] { parentFolder }.Concat(data.SubFolders ?? new List<CmsMedia>());

                        model.CmsMedia = data;
                        model.SubFolders = data.SubFolders.ToList();
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(searchQuery))
            {
                mediaContents = MediaContentService.FindByKeywords(searchQuery, id);
                ViewBag.MediaSearchQuery = searchQuery;
                ViewBag.IsPartialContent = true;
            }

            if (mediaContents != null)
            {
                if (orderBy == "ZA")
                {
                    mediaContents = mediaContents.OrderByDescending(e => e.MediaContentName);
                }
                else if (orderBy == "Updated")
                {
                    mediaContents = mediaContents.OrderByDescending(e => e.DateLastUpdated.GetValueOrDefault(e.DateCreated));
                }
                else
                {
                    mediaContents = mediaContents.OrderBy(e => e.MediaContentName);
                }

                int pageSize = size.GetValueOrDefault(32);
                int pageIndex = page.GetValueOrDefault(1);
                if (!isInAjax)
                {
                    model.Contents = mediaContents != null ? mediaContents.ToList() : null;
                    result = View(model);
                }
                else
                {
                    result = PartialView("MediaContentList",
                                            mediaContents.Skip((pageIndex - 1) * pageSize).Take(pageSize));
                }
            }
            else
            {
                if (!isInAjax)
                {
                    model.Contents = mediaContents != null ? mediaContents.ToList() : null;
                    result = View(model);
                }
                else
                {
                    result = PartialView("MediaContentList", new List<CmsMediaContent>());
                }
            }

            ViewBag.OrderBySelectList = new SelectList(OrderByModes, "Value", "Text", orderBy);
            return result ?? RedirectToAction("Index");
        }

        public ActionResult Edit(int id)
        {
            ActionResult result = null;

            if (id > 0)
            {
                var data = _mediaService.FindOne(id);
                if (data != null)
                {
                    SetFolders(id);
                    result = View(data);
                }
            }

            return result ?? RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult Edit(CmsAdminMediaSaveModel model)
        {
            ActionResult result = null;

            if (model != null)
            {
                if (!string.IsNullOrEmpty(model.Delete))
                {
                    var mediaItems = _mediaService.FindAllWithSubfolders();
                    if (mediaItems != null)
                    {
                        var mediaFileItems = _cmsMediaFileService.FindByFolderIds(FilterMediaByParentMediaId(mediaItems, model.Id).Select(x => x.Id));

                        if (mediaFileItems != null)
                        {
                            mediaFileItems.Remove();

                            _cmsMediaFileService.RemoveByIds(mediaFileItems.Select(x => x.Id));
                        }
                    }
                    _mediaService.Remove(model.Id);

                    return RedirectToAction("Index");
                }
                if (ModelState.IsValid)
                {
                    _mediaService.Save(model.ConvertToMedia());

                    result = !model.ParentMediaId.HasValue
                                 ? RedirectToAction("Index")
                                 : RedirectToAction("Get", new { id = model.ParentMediaId.Value });
                }
                else
                {
                    SetFolders(model.Id);
                }
            }

            return result ?? View(model.ConvertToMedia());
        }

        public ActionResult MediaNotFound()
        {
            return View();
        }

        public ActionResult SelectMedia(int? id)
        {
            var data = _mediaService.FindAllWithSubfolders() ?? new List<CmsMedia>();

            return PartialView(new CmsAdminMediaModel(data.ToList(), id));
        }

        public ActionResult View(int id)
        {
            ActionResult result = null;

            if (id > 0)
            {
                var data = MediaContentService.FindOne(id);

                if (data != null)
                {
                    var media = _mediaService.FindOne(data.MediaId);

                    if (media != null)
                    {
                        media.MediaContents = media.MediaContents.Where(c => c.Id == id);
                    }

                    ViewBag.OrderBySelectList = new SelectList(OrderByModes, "Value", "Text");
                    ViewBag.IsPartialContent = true;

                    var model = new CmsMediaModel { CmsMedia = media, Contents = media.MediaContents.ToList() };
                    result = View("Get", model);
                }
            }

            return result ?? RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult ChangeFolderParent(int id, int newId)
        {
            var media = _mediaService.FindOne(id);
            if (newId != 0)
            {
                media.ParentMediaId = newId;
            }
            else
            {
                media.ParentMediaId = null;
            }
            _mediaService.Save(media);
            return Content("1");
        }

        [HttpPost]
        public ActionResult ChangeContentFolder(int id, int newId)
        {
            var media = MediaContentService.FindOne(id);
            media.MediaId = newId;
            _mediaContenService.Save(media);
            return Content("1");
        }

        public ActionResult CreateNewFolder()
        {
            SetFolders();
            return Request.IsAjaxRequest() ?
                PartialView("MediaDetails", new CmsMedia()) as ActionResult :
                new EmptyResult();
        }

        private IEnumerable<CmsMedia> FilterMediaByParentMediaId(IEnumerable<CmsMedia> media, int parentMediaId)
        {
            var result = new List<CmsMedia>();
            foreach (var cmsMedia in media)
            {
                if (cmsMedia.Id == parentMediaId)
                {
                    result.Add(cmsMedia);
                }
                else if (cmsMedia.ParentMediaId == parentMediaId || (result.Any(x => x.Id == cmsMedia.ParentMediaId)))
                {
                    result.Add(cmsMedia);
                }
            }
            return result;
        }
    }
}